/*
 * Copyright (C) 2000-2008 Jens Nixdorf and various contributors
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies of the Software, its documentation and marketing & publicity
 * materials, and acknowledgment shall be given in the documentation, materials
 * and software packages that this Software was used.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
package org.mopore.jat.core.fadingmessage.calibration.wizard;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextPane;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.mopore.jat.core.fadingmessage.calibration.CalibrationInfo;
import org.mopore.jat.core.fadingmessage.calibration.ICalibtrationAccessor;
import org.mopore.jat.core.fadingmessage.calibration.ICalibtrationInfoReciever;
import org.mopore.jat.core.fadingmessage.calibration.visual.VisualCalibtration;
import org.mopore.jat.gui.Theme;
import org.mopore.jat.gui.SingleRoundCornerRectangleFactory.CornerType;
import org.mopore.jat.gui.wizard.AbstractWizardPage;
import org.mopore.jat.gui.wizard.ButtonPanel;
import org.mopore.jat.plugin.PluginException;
import org.mopore.jat.util.TextService;

public class PerformCalibtrationPage 
	extends AbstractWizardPage<CalibrationInfo> implements ICalibtrationInfoReciever {
	
	private final Log log = LogFactory.getLog(getClass().getName());
	private static final String VERTICAL_OFFSET = "calibtrated vertical offset: ";
	private static final String HORIZONTAL_OFFSET = "calibtrated horizontal offset: ";
	private Integer horizontalOffset;
	private Integer verticalOffset;
	private JLabel hLabel;
	private JLabel vLabel;

	@Override
	public JPanel getContentPanel(){
		
		ButtonPanel buttonPanel = getButtonPanel();
		buttonPanel.addActionToBackButton(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				changePage( ChooseCornerPage.class );
			}
		});
		buttonPanel.enableBackButton();
		
		CalibrationWizardContext context = 
			(CalibrationWizardContext) context();
		
		final ICalibtrationAccessor calibtrationAccessor = context.getAccessor();
		buttonPanel.addActionToFinishButton( new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				log.info( "store calibtraiton info to filesystem...");
				CalibrationInfo info = 
					PerformCalibtrationPage.this.context().get();
				try {
					calibtrationAccessor.store( info );
					log.info( "new calibration stored." );
					Theme theme = calibtrationAccessor.getTheme();
					showConfirmationMessage( info, theme );
					
				} catch ( PluginException exception ) {
					String errorMessage = "Can not persist calibration of window message!";
					log.error( errorMessage, exception );
					throw new InternalError( errorMessage );
				}
			}
			} 
		);
		
		final CalibrationInfo info = context().get();
		boolean canBeFinished = ! info.isInitCalibration();
		if ( canBeFinished ){
			buttonPanel.enableFinishButton();
		}
		
		
		
		JPanel panel = new JPanel();
		
		panel.setLayout( null );
		
		JTextPane textPane = 
			new JTextPane();
		textPane.setEditable( false );
		textPane.setBackground( null );
		textPane.setBounds( 4, 7, 320, 128 );
		
		String text = TextService.readText( "/texts/performCalibtration.txt" );
		textPane.setText( "Step 2: Calibrate the message window position.\n" +
				text  );
		panel.add( textPane );
		

		String horizontalOffsetText = createOffsetString( HORIZONTAL_OFFSET, 
				info.getHorizontalOffset(), info.isInitCalibration() );
		
		String verticalOffsetText = createOffsetString( VERTICAL_OFFSET, 
				info.getVerticalOffset(), info.isInitCalibration() );
		
		hLabel = new JLabel( horizontalOffsetText );
		hLabel.setBounds( 4, 147, 300, 25 );
		hLabel.setVerticalAlignment( JLabel.CENTER );
		panel.add( hLabel );		
		
		vLabel = new JLabel( verticalOffsetText );
		vLabel.setBounds( 4, 154, 300, 40 );
		vLabel.setVerticalAlignment( JLabel.CENTER );
		panel.add( vLabel );
		
		JButton calibrateButton = new JButton( "calibrate..." );
		calibrateButton.setBounds( 120, 190, 100, 40 );
		calibrateButton.addActionListener( new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent e) {
				int verticalOffset = info.getVerticalOffset();
				int horizontalOffset = info.getHorizontalOffset();
				CornerType cornerType = info.getCornerType();
				try {
					Runnable runnable = 
						new VisualCalibtration( PerformCalibtrationPage.this,
							cornerType, horizontalOffset, verticalOffset );
					Thread t = new Thread(runnable);
					t.start();
				}
				catch( Exception exception ){
					throw new RuntimeException( exception );
				}
			}
		});
		panel.add( calibrateButton );
		
		panel.setBorder( BorderFactory.createEmptyBorder( 0, 10, 0, 10) );
		
		return panel;
	}


	private String createOffsetString( String preText, Integer offset, boolean initialSetup ) {
		String offsetText;
		if ( initialSetup ){
			offsetText = "<not yet calibrated>";
		}
		else {
			offsetText = String.valueOf( offset );
		}
		return preText + offsetText;
	}


	@Override
	public void storeToContext() {
		CalibrationInfo info = context().get();
		info.setHorizontalOffset( horizontalOffset );
		info.setVerticalOffset( verticalOffset );
	}


	@Override
	public void recieveCalibrationInfo(CalibrationInfo calibrationInfo) {
		horizontalOffset = calibrationInfo.getHorizontalOffset();
		String hText = createOffsetString(  HORIZONTAL_OFFSET, 
				horizontalOffset, calibrationInfo.isInitCalibration() );
		hLabel.setText( hText );
				
		verticalOffset = calibrationInfo.getVerticalOffset();
		String vText = createOffsetString( VERTICAL_OFFSET, verticalOffset,
				 calibrationInfo.isInitCalibration() );
		vLabel.setText( vText );
		
		CalibrationInfo info = context().get();
		info.setInitCalibration( false );
		
		ButtonPanel buttonPanel = getButtonPanel();
		buttonPanel.enableFinishButton();
		
		context().repaintAll();
	}
	
	
	private void showConfirmationMessage(CalibrationInfo info, Theme theme) {
		
		CalibrationWizardContext context = 
			(CalibrationWizardContext) context();
		ICalibtrationAccessor accessor = context.getAccessor();
		
		accessor.showConfirmMessage( );
	}
	
}
